package com.freewater.library.lending.checkedoutsheet.model;

import com.freewater.library.catalogue.model.Book;
import com.freewater.library.common.domain.Nullable;
import com.freewater.library.lending.book.model.BookInstance;
import com.freewater.library.lending.reader.model.Reader;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.Validate;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 借出记录
 */
@Data
@Entity
@NoArgsConstructor
@Table(name = "checked_out_record",
        uniqueConstraints = {
                @UniqueConstraint(columnNames = {"qr_code", "checked_out_by", "checked_out_at"})
        })
@EqualsAndHashCode(of = {"qrCode", "checkedOutBy", "checkedOutAt"})
public class CheckedOutRecord {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    /**
     * 二维码
     */
    private String qrCode;
    /**
     * 借出读者ID
     */
    private Long checkedOutBy;
    /**
     * 借出时间
     */
    private LocalDateTime checkedOutAt;
    /**
     * 借出读者姓名
     */
    private String checkedOutByName;
    /**
     * 书ISBN
     */
    private String isbn;
    /**
     * 标题
     */
    private String title;
    /**
     * 副标题
     */
    private String subtitle;
    /**
     * 作者
     */
    private String author;
    /**
     * 出版社
     */
    private String publishingHouse;
    /**
     * 封面图
     */
    private String cover;
    /**
     * 丛书
     */
    private String series;
    /**
     * 是否已逾期
     */
    private boolean overdue;
    /**
     * 是否遗失
     */
    private boolean lost;
    /**
     * 遗失时间
     */
    private LocalDateTime lostTime;
    /**
     * 是否已归还
     */
    private boolean returnBack;
    /**
     * 归还时间
     */
    private LocalDateTime returnBackTime;

    public CheckedOutRecord(Book book,
                            BookInstance bookInstance,
                            Reader checkOutReader,
                            @Nullable LocalDateTime checkedOutAt) {
        Validate.notNull(book, "书不能为空");
        Validate.notNull(bookInstance, "预定书不能为空");
        Validate.notNull(checkOutReader, "借出读者不能为空");
        this.qrCode = bookInstance.getQrCode();
        this.checkedOutBy = checkOutReader.getId();
        this.checkedOutAt = checkedOutAt == null ? LocalDateTime.now() : checkedOutAt;
        this.checkedOutByName = checkOutReader.getName();
        this.isbn = book.getIsbn();
        this.title = book.getTitle();
        this.subtitle = book.getSubtitle();
        this.author = book.getAuthor();
        this.publishingHouse = book.getPublishingHouse();
        this.cover = book.getCover();
        this.series = book.getSeries();
        this.overdue = false;
        this.lost = false;
        this.lostTime = null;
        this.returnBack = false;
        this.returnBackTime = null;
    }

    public void overdue() {
        this.overdue = true;
    }

    public void lost(LocalDateTime lostTime) {
        Validate.notNull(lostTime, "遗失时间不能为空");
        this.lost = true;
        this.lostTime = lostTime;
    }

    public void returnBack(LocalDateTime returnBackTime) {
        Validate.notNull(returnBackTime, "归还时间不能为空");
        this.returnBack = true;
        this.returnBackTime = returnBackTime;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Unique implements Serializable {
        /**
         * 二维码
         */
        private String qrCode;
        /**
         * 借出读者ID
         */
        private Long checkedOutBy;
        /**
         * 借出时间
         */
        private LocalDateTime checkedOutAt;
    }
}
